@page "/TicketProcessHandler/{TicketID}"

 
@rendermode InteractiveServer




<div class="container mt-4">
    @if (WorkOrder == null)
    {
        <p class="text-danger">未找到工单信息。</p>
    }
    else
    {
        <Ticket TicketID="@TicketID"   @ref="TicketComponent"></Ticket>

<hr />
<h5 class="text-primary"><i class="fas fa-tasks me-2"></i>操作面板</h5>
<Card>
    <BodyTemplate>
    @{
        switch (CurrentNode?.操作类型)
        {
            case OperationType.审批:
                @if(hasApprovalPermission)
                {
                    <div class="mb-3">
                        <label class="form-label"><i class="fas fa-comment-dots me-2"></i>审批意见</label>
                        <Textarea class="form-control mb-3" @bind-Value="CommentContent" 
                                  placeholder="请输入审批意见..." rows="3"></Textarea>
                       <div  class="btn-group  col-12" role="group" >
                            <Button  IsBlock="true" Color="Color.Danger" Text="审批拒绝" Icon="fas fa-times-circle me-2" OnClick="RejectWorkOrder"/>
                             <Button  IsBlock="true" Color="Color.Primary"Text="审批通过" Icon="fas fa-check-circle me-2" OnClick="ApproveWorkOrder"/>
                        </div>
                     
                       
                              
                       
                    </div>
                }
                else
                {
                    <div class="alert alert-warning" role="alert">
                        <i class="fas fa-exclamation-triangle me-2"></i>
                        您没有审批权限，无法进行审批操作
                    </div>
                }
                break;

            case OperationType.分派:
                @if(hasApprovalPermission)
                {
             
    
           
                        <BootstrapInputGroup>
                        <BootstrapInputGroupLabel DisplayText="请选择处理人" />
                            <Select @bind-Value="AssigneeId" 
                                   ShowSearch="true" 
                                   IsClearable="true" 
                                   Items="@User"></Select>
                            <Button   Color="Color.Primary"  Text="确认分派" Icon="fas fa-user-check me-2" OnClick="AssignWorkOrder">
                            </Button>
                        </BootstrapInputGroup>
                   
                }
                else
                {
                    <div class="alert alert-warning" role="alert">
                        <i class="fas fa-exclamation-triangle me-2"></i>
                        您没有分派权限，无法进行分派操作
                    </div>
                }
                break;

            case OperationType.处理:
                @if (IsAssignedToCurrentUser&&hasApprovalPermission)
                {

            <ValidateForm Model="@处理内容s" OnValidSubmit="@CompleteWorkOrder">
                <div class="mb-3">
                    <label class="form-label"><i class="fas fa-file-alt me-2"></i>处理说明</label>
                    
                    <CardUpload TValue="IBrowserFile" ShowLabel="false" 
                            @bind-Value="处理内容s.UploadedFile" 
                            ShowProgress="true"  
                         
                            OnChange="@OnCardUpload" 
                            OnDelete="@OnDelete" />
                    
                    <!-- 修改验证消息绑定 -->
                 <ValidationMessage For="@(() => 处理内容s.HasValidFilesForValidation)" />
                    
                    <Textarea class="form-control mb-3" @bind-Value="@处理内容s.处理意见" 
                            placeholder="请输入处理说明..." rows="3"></Textarea>
                    

                        <div  class="btn-group  col-12" role="group" >

                               <Button  IsBlock="true" Color="Color.Danger"Text="处理失败" Icon="fas fa-times-circle me-2"  OnClick="@(async () => await CompleteWorkOrderWithFailure())" />
                            <Button  IsBlock="true"  ButtonType="ButtonType.Submit" IsAsync="true"  Color="Color.Primary" Text="处理完成" Icon="fas fa-check-double me-2" />
                          
                        </div>

                </div>
            </ValidateForm>
                }
                else
                {
                    <div class="alert alert-warning" role="alert">
                        <i class="fas fa-user-lock me-2"></i>
                        您不是分配的处理人，无法处理此工单
                    </div>
                }
                break;

            default:
                <div class="alert alert-info" role="alert">
                    <i class="fas fa-info-circle me-2"></i>
                    当前节点没有定义操作
                </div>
                break;
        }
    }
    </BodyTemplate>
</Card>
     
     
    }
</div>

@code {
public class 处理内容
{
    [Required(ErrorMessage = "请输入处理意见")]
    public string 处理意见 { get; set; } = string.Empty;
    [Required(ErrorMessage = "请上传文件或已有文件")]

    // 移除 UploadedFile 的 Required 特性
    public IBrowserFile? UploadedFile { get; set; }
 

// 在 处理内容 类中添加
    [Required(ErrorMessage = "请上传文件或已有文件")]
    public bool HasValidFilesForValidation => UploadedFile != null ;
    // 自定义验证方法
   
}
   
    [Inject]
    private IWebHostEnvironment? Environment { get; set; }
    private Ticket? TicketComponent;
    [Parameter]
    [Required] 
    public required string TicketID { get; set; }
    [Inject]
    [NotNull]
 
    private ToastService? ToastService { get; set; }
     [Inject]
    [NotNull]
    private IWorkOrderService? WorkOrderService { get; set; }
    [Inject]
    [NotNull]
    private ISystemNotificationService SystemNotificationService { get; set; }
    private List<SelectedItem> User { get; set; } = new();
    [Inject]
    private MyIdentityContext AppContext { get; set; } 
 
    private CancellationTokenSource? ReadToken { get; set; }

    private 处理内容 处理内容s { get; set; } = new 处理内容();
    private string CommentContent { get; set; } = string.Empty;
    private static long MaxFileLength => 5 * 1024 * 1024;
    [Inject]
    private IUser   UserService { get; set; } 
    private 工单主表? WorkOrder { get; set; }
    private 工单流程实例表? ProcessInstance { get; set; }
    private 流程节点表? CurrentNode { get; set; } 

    private string AssigneeId { get; set; } = string.Empty;
    
    private bool IsAssignedToCurrentUser { get; set; } = false;


 
    private bool hasApprovalPermission { get; set; } = false;

    protected override async Task OnInitializedAsync()
    {
 

            await LoadWorkOrderDetailsAsync();


        // 初始化用户列表
       
    }


     private async Task OnCardUpload(UploadFile file)
    {
        if (file != null && file.File != null)
        {
            // 服务器端验证当文件大于 5MB 时提示文件太大信息
            if (file.Size > MaxFileLength)
            {
                await ToastService.Information("上传文件", "文件大小超过 5MB");
                file.Code = 1;
                file.Error = "文件大小超过 5MB";
    
            }
            else
            {
                await SaveToFile(file);
       
            }
        }
    }


      private async Task<bool> SaveToFile(UploadFile file)
    {
     

        var ret = false;
        if (!string.IsNullOrEmpty(Environment.WebRootPath))
        {
            var uploaderFolder = Path.Combine(Environment.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader");
            file.FileName = $"{Path.GetFileNameWithoutExtension(file.OriginFileName)}-{DateTimeOffset.Now:yyyyMMddHHmmss}{Path.GetExtension(file.OriginFileName)}";
            var fileName = Path.Combine(uploaderFolder, file.FileName);

            ReadToken ??= new CancellationTokenSource();
            ret = await file.SaveToFileAsync(fileName, MaxFileLength, ReadToken.Token);

            if (ret)
            {

               
               
                // 保存成功
                file.PrevUrl = $"/images/uploader/{file.FileName}";
                await   WorkOrderService.AddFlieAsync(new 工单附件表()
                {
                     文件名 = file.FileName,
                     存储路径 = file.PrevUrl,
                     文件大小 = file.Size,
                     文件类型 = file.File.ContentType,
                     工单id = TicketID,
                     用户id = AppContext.UserName,
                     上传时间 = DateTime.Now,
                     是否提交=false,
                });
                @* 处理内容s.SavedFiles.Add(file); *@
            }
            else
            {
                var errorMessage = $"{"保存文件失败"} {file.OriginFileName}";
                file.Code = 1;
                file.Error = errorMessage;
                await ToastService.Error("上传文件", errorMessage);
            }
        }
        else
        {
            file.Code = 1;
            file.Error = "Wasm 模式未实现保存代码";
            await ToastService.Information("保存文件", "当前模式为 WebAssembly 模式，请调用 Webapi 模式保存文件到服务器端或数据库中");
        }
        return ret;
    }
    private  async Task<bool> OnDelete(UploadFile file)
    {
        // 删除文件
        if (file != null && file.File != null)
        {   
            if(file.Code==1)
            {
              return await Task.FromResult(true);
            }
            var uploaderFolder = Path.Combine(Environment.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader");
            var fileName = Path.Combine(uploaderFolder, file.FileName);
            if (File.Exists(fileName))
            {
                File.Delete(fileName);
              
                await WorkOrderService.DeleteFlieAsync(file.FileName,TicketID);
     
                return true;
            }
        }

        return false;
    }
private async Task LoadWorkOrderDetailsAsync()
{
    try
    {
        // 加载工单信息
        WorkOrder = await WorkOrderService.GetWorkOrderByIdAsync(TicketID);
        if (WorkOrder == null)
        {
            await ToastService.Warning("未找到工单信息。");
            return;
        }

 
  

        // 加载流程实例信息
        ProcessInstance = await WorkOrderService.GetProcessInstanceByWorkOrderIdAsync(TicketID);
        if (ProcessInstance == null)
        {
            await ToastService.Warning("未找到工单的流程实例信息。");
            return;
        }

        // 加载当前节点信息
        CurrentNode = ProcessInstance.当前节点;
     
 
         await  CheckPermissions();
          User = await GetUserlist();
      
    }
    catch (Exception ex)
    {
        await ToastService.Error("失败",$"加载工单信息失败：{ex.Message}");
    }
}
 



    private async Task ApproveWorkOrder()
    {
        try
        {
            // 审批通过逻辑
         await WorkOrderService.TransitionToNextNodeAsync(TicketID, AppContext.UserName);
         await WorkOrderService.AddCommentAsync(CommentType.审批评论, TicketID, AppContext.UserName, CommentContent??"同意审批");
                  await SystemNotificationService.SendNotificationAsync(Constant.UserMessagge, DispatchType.Toast,"成功",$"您的工单已被{AppContext.UserName}审批通过，工单已流转到下一步骤",WorkOrder.创建人id);
         await   ToastService.Success("成功","审批通过！");
         StateHasChanged();
        }
        catch (Exception ex)
        {
         await   ToastService.Error("失败",$"审批失败：{ex.Message}");
      
        }
        finally{ await LoadWorkOrderDetailsAsync();
                   await TicketComponent.RefreshAsync();}
    }

    private async Task RejectWorkOrder()
    {
        try
        {
            // 调用后端服务，直接关闭工单

            await WorkOrderService.CloseWorkOrderAsync(TicketID, AppContext.UserName, "审批拒绝");
            await WorkOrderService.AddCommentAsync(CommentType.审批评论, TicketID, AppContext.UserName, CommentContent??"审批拒绝");
            await ToastService.Error("失败","审批拒绝，工单已关闭！");
            await SystemNotificationService.SendNotificationAsync(Constant.UserMessagge, DispatchType.Toast,"失败",$"您的工单已被{AppContext.UserName}审批拒绝，工单已关闭",WorkOrder.创建人id);
            StateHasChanged();
        }
        catch (Exception ex)
        {
            await ToastService.Error("失败",$"审批失败：{ex.Message}");
        }
            finally{ await LoadWorkOrderDetailsAsync();
                 await TicketComponent.RefreshAsync();}
    }

    private async Task AssignWorkOrder()
    {
        try
        {
            // 分派逻辑
            if (string.IsNullOrEmpty(AssigneeId))
            {
                await ToastService.Warning("警告","请选择处理人！");
                return;
            }
       
            await WorkOrderService.ChangeAssigneeAsync(TicketID, new List<string> { AssigneeId }, AppContext.UserName, "分派工单给处理人");
            await SystemNotificationService.SendNotificationAsync(Constant.UserMessagge, DispatchType.Toast,"成功",$"您的工单已被{AppContext.UserName}分配给{AssigneeId}。等到处理",WorkOrder.创建人id);
            await SystemNotificationService.SendNotificationAsync(Constant.UserMessagge, DispatchType.Toast,"成功",$"{WorkOrder.创建人id}创建的工单已被{AppContext.UserName}分配给您请尽快处理",AssigneeId);
            await    ToastService.Success("成功","工单已分派！");
             StateHasChanged();
        }
        catch (Exception ex)
        {
           await ToastService.Error($"分派失败：{ex.Message}");
        }
              finally{ await LoadWorkOrderDetailsAsync();    await TicketComponent.RefreshAsync();}
    }
        private async Task CompleteWorkOrder(EditContext context)
        {
            try
            {
            
                

                await WorkOrderService.CompleteWorkOrderAndDeductAsync(TicketID, AppContext.UserName,"工单完成");
                await WorkOrderService.AddCommentAsync(CommentType.处理评论, TicketID, AppContext.UserName,  处理内容s.处理意见?? "完成工单处理");
                await ToastService.Success("成功", "工单已处理完成！");


                
                await SystemNotificationService.SendNotificationAsync(Constant.UserMessagge, DispatchType.Toast,"成功",$"工单已处理完成！",WorkOrder.创建人id);
                    
                
                await  LoadWorkOrderDetailsAsync();
                处理内容s= new 处理内容();
                StateHasChanged();
                
            }
            catch (Exception ex)
            {
                await ToastService.Error($"处理失败：{ex.Message}");
            }
            finally
            {
                
                await LoadWorkOrderDetailsAsync();
                
                await TicketComponent.RefreshAsync();
            
            }
        }

    private async Task CompleteWorkOrderWithFailure()
    {
        try
        {
         
 

            await WorkOrderService.CloseWorkOrderAsync(TicketID, AppContext.UserName, "处理拒绝");
            await WorkOrderService.AddCommentAsync(CommentType.处理评论, TicketID, AppContext.UserName,  处理内容s.处理意见?? "完成工单处理");
            await SystemNotificationService.SendNotificationAsync(Constant.UserMessagge, DispatchType.Toast,"失败",$"您有一个提交的工单处理失败请查看!",WorkOrder.创建人id);
            await ToastService.Error("失败", "工单处理失败");
           StateHasChanged();
        }
        catch (Exception ex)
        {
             await ToastService.Error($"处理失败：{ex.Message}");
        }
        finally
        {
            
            await LoadWorkOrderDetailsAsync();
            
            await TicketComponent.RefreshAsync();
          
        }
    }
    private async Task CheckPermissions()
{
    if (CurrentNode == null || AppContext.UserName == null) 
    {
        hasApprovalPermission = false;
        IsAssignedToCurrentUser = false;
        return;
    }

    // 获取节点权限信息
    var permissionInfo = await WorkOrderService.GetProcessInstanceByWorkOrderIdAsync(TicketID);
    CurrentNode=permissionInfo.当前节点;
    // 检查当前用户是否有权限
    hasApprovalPermission = permissionInfo?.当前节点 != null && 
                            (permissionInfo.当前节点.负责人规则类型 switch
                            {
                                AssignRuleType.角色 => AppContext.Roles.Contains(permissionInfo.当前节点.负责人规则参数),
                                AssignRuleType.指定用户 => permissionInfo.当前节点.负责人规则参数 == AppContext.UserName,
                                _ => false
                            } || AppContext.Roles.Contains("Administrator"));

    // 判断是否是当前处理人或管理员
    IsAssignedToCurrentUser = (WorkOrder?.工单分派记录表s.Any(cm => cm.是否当前负责人 == true && cm.用户id == AppContext.UserName) ?? false) 
                              || (AppContext.Roles?.Contains("Administrator") ?? false);

 
   

    // 如果是分派节点，加载可分配人员
   
}

public async Task<List<SelectedItem>> GetUserlist()
{
    // 1. 获取下一节点（处理订单节点）
    var permissionInfo = await WorkOrderService.GetProcessInstanceByWorkOrderIdAsync(TicketID);
    var 下一节点 = permissionInfo?.当前节点?.源节点?.FirstOrDefault();
    if (下一节点 == null) return new List<SelectedItem>();

    var 节点详情 = await WorkOrderService.GetRoute(下一节点.目标节点ID);
    if (节点详情 == null) return new List<SelectedItem>();

    // 2. 根据下一节点的负责人规则筛选用户
    switch (节点详情.负责人规则类型)
    {
        case AssignRuleType.角色:
            return UserService.GetUsersByRoleName(节点详情.负责人规则参数)?.ToSelectedItemList2() ?? new List<SelectedItem>();

        default:
            return UserService.GetAll()?.ToSelectedItemList2() ?? new List<SelectedItem>();
    }
}
}